]> git.plutz.net Git - rigidfind/blobdiff - index.cgi
bugfix: time calculation
[rigidfind] / index.cgi
index d4f4cec6f8ed573ce27032ccdf9b0467798d0fee..945d133985a5ddc242bc062a2ce1d39b280f762e 100755 (executable)
--- a/index.cgi
+++ b/index.cgi
@@ -1,15 +1,17 @@
 #!/bin/sh
 
+read _DATE _date_n <<-EOF
+       $(date +"%s     %N")
+       EOF
+
 . "${_EXEC:-${0%/*}}/cgilite/cgilite.sh"
 . "${_EXEC:-${0%/*}}/cgilite/storage.sh"
 . "${_EXEC:-${0%/*}}/cgilite/json.sh"
 
-[ "$_DATE" ] || _DATE="$(date +%s)"
-
-debug "$REQUEST_METHOD $REQUEST_URI    $SERVER_PROTOCOL"
+debug "$REQUEST_METHOD $REQUEST_URI    $SERVER_PROTOCOL        $_DATE"
 
 ingest() {
-  local J="$1"
+  local J="$1" ztmp="${TMP:-/tmp}/zipfile_$$.zip"
 
   # json_get "$J" title
   # json_get "$J" parts.comments
@@ -39,24 +41,28 @@ ingest() {
       | sed 's;<[^>]*>;;g'
       ;;
     *.docx)
-      printf %s "$content" |base64 -d \
-      | unzip -qc /dev/stdin word/document.xml \
+      printf %s "$content" |base64 -d >"$ztmp"
+      unzip -qc "$ztmp" word/document.xml \
       | head -c 128M | sed 's;<[^>]*>;;g'
+      rm -- "$ztmp"
       ;;
     *.xlsx)
-      printf %s "$content" |base64 -d \
-      | unzip -qc /dev/stdin xl/sharedStrings.xml \
+      printf %s "$content" |base64 -d >"$ztmp"
+      unzip -qc "$ztmp" xl/sharedStrings.xml \
       | head -c 128M | sed 's;<[^>]*>; ;g'
+      rm -- "$ztmp"
       ;;
     *.odt)
-      printf %s "$content" |base64 -d \
-      | unzip -qc /dev/stdin content.xml \
+      printf %s "$content" |base64 -d >"$ztmp"
+      unzip -qc "$ztmp" content.xml \
       | head -c 128M | sed 's;<[^>]*>;;g'
+      rm -- "$ztmp"
       ;;
     *.ods|*.odp)
-      printf %s "$content" |base64 -d \
-      | unzip -qc /dev/stdin content.xml \
+      printf %s "$content" |base64 -d >"$ztmp"
+      unzip -qc "$ztmp" content.xml \
       | head -c 128M | sed 's;<[^>]*>; ;g'
+      rm -- "$ztmp"
       ;;
     *):;;
   esac
@@ -105,6 +111,23 @@ search() {
 _INDEX="${PATH_INFO#/}" _INDEX="${_INDEX%%/*}"
 _records="${_DATA}/${_INDEX}/_0_DOCS"
 
+if [ "${INDEX}" -a ! -d "${_DATA}/${_INDEX}" ]; then
+  printf '%s\r\n' "Status: 404 Not Found" ""
+  exit 0
+elif authlist="$(DBM "${_DATA}/auth.db" get "${_INDEX}" )"; then
+  auth="$(HEADER Authorization)" auth="${auth#Basic }"
+  for a in $authlist deny; do
+    [ "$auth" = "$a" ] && break
+  done
+  if [ "$a" = "deny" -o ! "$auth" ]; then
+    printf '%s\r\n' "Status: 401 Unauthorized" \
+      "WWW-Authenticate: Basic realm=\"Rigid Find\"" "" \
+    | debug
+    exit 0
+  fi
+  unset a auth authlist
+fi
+
 if   [ "$REQUEST_METHOD" = "PUT" ]; then
   _doc="${PATH_INFO#"/${_INDEX}/_doc"}"
 
@@ -122,15 +145,23 @@ if   [ "$REQUEST_METHOD" = "PUT" ]; then
     s;,[ \t\r\n]*"content"[ \t\r\n]*:[ \t\r\n]*"[^"]*";;
   ')"
   J="$(json_load "${J}")"
-  
-  ingest "$J" "$content"\
-  | "${_EXEC}/concordance.sh" \
-    "$_DATA/$_INDEX/" "$(STRING "$_doc")       $_DATE"
+
+  debug "Content: ${#content} bytes"
+  debug "$(json_dump "$J")"
+
+  if [ "${#content}" -gt 0 ]; then
+    ingest "$J" "$content"\
+    | "${_EXEC}/concordance.sh" \
+      "$_DATA/$_INDEX/" "$(STRING "$_doc")     $_DATE"
+  fi
 
   J="${J#obj:}"
   J="$(DB2 "$J" set _indexdate num:"$_DATE")"
 
-  if   DBM "$_records" insert "$_doc" "$J"; then
+  if [ "${#content}" -eq 0 ]; then
+    printf '%s: %s\r\n' "Status" "200 OK"
+    result="updated"
+  elif DBM "$_records" insert "$_doc" "$J"; then
     printf '%s: %s\r\n' "Status" "201 Created" "Location" "/${_INDEX}/_doc/$(URL "$_doc")" \
     result="created"
   elif DBM "$_records" update "$_doc" "$J"; then
@@ -141,10 +172,10 @@ if   [ "$REQUEST_METHOD" = "PUT" ]; then
     exit 0
   fi
 
-  sed 's;$;\r;' <<-EOF
-       X-elastic-product: Elasticsearch
-       content-type: application/vnd.elasticsearch+json;compatible-with=8
-
+  cat <<-EOF
+       X-elastic-product: Elasticsearch\r
+       content-type: application/vnd.elasticsearch+json;compatible-with=8\r
+       \r
        { "_index": $(json_dump str:"${_INDEX}"),
          "_id": $(json_dump str:"$_doc"),
          "result": "$result",
@@ -169,10 +200,10 @@ elif [ "$REQUEST_METHOD" = "DELETE" ]; then
     result="not_found"
   fi
 
-  sed 's;$;\r;' <<-EOF
-       X-elastic-product: Elasticsearch
-       content-type: application/vnd.elasticsearch+json;compatible-with=8
-
+  cat <<-EOF
+       X-elastic-product: Elasticsearch\r
+       content-type: application/vnd.elasticsearch+json;compatible-with=8\r
+       \r
        { "_index": $(json_dump str:"${_INDEX}"),
          "_id": $(json_dump str:"$_doc"),
          "result": "$result",
@@ -188,12 +219,14 @@ elif [ "$REQUEST_METHOD" = "POST" ]; then
   words="$(
     for j in $(DB2 "$J" iterate @); do
       json_get "$(UNSTRING "$j")" match_phrase_prefix.content
-    done 2>/dev/null
+    done 2>/dev/null |tr \\n ' '
   )"
+  debug "Search words: $words"
 
   results="@   $(
     search "${_DATA}/${_INDEX}" $words \
     | while read -r score id source; do
+      debug "Hit: $id  $score"
       S="$(DB2   "" set _index  str:"${_INDEX}")"
       S="$(DB2 "$S" set _id     str:"$(UNSTRING "${id#/}")")"
       S="$(DB2 "$S" set _score  num:"$score")"
@@ -203,17 +236,18 @@ elif [ "$REQUEST_METHOD" = "POST" ]; then
   )"
   results="${results%  }"
 
-  sed 's;$;\r;' <<-EOF
-       Status: 200 OK
-       X-elastic-product: Elasticsearch
-       Content-Type: application/vnd.elasticsearch+json;compatible-with=8
+  t="$(( $(date +%s%N) - ${_DATE}${_date_n} ))"
 
-       { "took":0,
+  cat <<-EOF
+       Status: 200 OK\r
+       X-elastic-product: Elasticsearch\r
+       Content-Type: application/vnd.elasticsearch+json;compatible-with=8\r
+       \r
+       { "took":$((t / 1000000)),
          "timed_out":false,
-         "_shards":{"total":1,"successful":1,"skipped":0,"failed":0},
          "hits": {
            "total":{"value": $(DB2 "$results" count @) ,"relation":"eq"},
-           "max_score": $(json_get "arr:$results" '[0]._score' 2>&- || printf 0),
+           "max_score": $(json_get "arr:$results" '[0]._score' 2>/dev/null || printf 0),
            "hits": $(json_dump "arr:$results")
          }
        }
@@ -224,74 +258,22 @@ elif [ "$REQUEST_METHOD" = "HEAD" ]; then
   [ ! "${accept#*"vnd.elasticsearch+json"*}" ] \
   && ctype="${accept}" || ctype="application/json"
 
-  sed 's;$;\r;' <<-EOF
-       HTTP/1.1 200 OK
-       X-elastic-product: Elasticsearch
-       content-type: ${ctype}
-
+  cat <<-EOF
+       Status: 200 OK\r
+       X-elastic-product: Elasticsearch\r
+       content-type: ${ctype}\r
+       \r
        EOF
   exit 0
 
-elif [ "$REQUEST_METHOD" = "GET" ]; then
-  accept="$(HEADER Accept)"
-  [ ! "${accept#*"vnd.elasticsearch+json"*}" ] \
-  && ctype="${accept}" || ctype="application/json"
-
-  sed 's;$;\r;' <<-EOF
-       HTTP/1.1 200 OK
-       X-elastic-product: Elasticsearch
-       content-type: ${ctype}
-
-       EOF
-       
-  if [ "$PATH_INFO" = "/${_INDEX}/" ]; then
-  sed 's;$;\r;' <<-EOF
-       { $(json_dump str:"${_INDEX}"): {
-           "aliases":{},
-           "mappings": {
-             "properties": {
-               "content": {"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},
-               "hash":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},
-               "metatags":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},
-               "owner":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},
-               "parts":{"properties":{"comments":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}}}},
-               "provider":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},
-               "share_names":{"properties":{"paul":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}}}},
-               "source":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},
-               "title":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}}
-             }
-           },
-           "settings": {
-             "index": {
-               "routing":{"allocation":{"include":{"_tier_preference":"data_content"}}},
-               "number_of_shards":"1",
-               "provided_name": $(json_dump str:"${_INDEX}"),
-               "creation_date": "$(stat -c %W "${_DATA}/${_INDEX}")",
-               "number_of_replicas":"1",
-               "uuid":"0000000000000000000000",
-               "version":{"created":"8500010"}
-             }
-           }
-         }
-       }
-       EOF
-  else
-    sed 's;$;\r;' <<-EOF
-       { "name" : "head",
-         "cluster_name" : "elasticsearch",
-         "version" : {
-           "number" : "8.12.1",
-           "lucene_version" : "9.9.2",
-           "minimum_wire_compatibility_version" : "7.17.0",
-           "minimum_index_compatibility_version" : "7.0.0"
-         },
-         "tagline" : "You Know, for Search"
-       }
-       EOF
-  fi
-  exit 0
-
 else
-  printf '%s\r\n' "Status: 500 Internal Server Error" ""
+  # elif [ "$REQUEST_METHOD" = "GET" ]; then
+  cat <<-EOF
+       Status: 501 Not Implemented\r
+       X-elastic-product: Elasticsearch\r
+       content-type: text/plain\r
+       \r
+       Use the Nextcloud Elastic Search Plugin to use this service.
+       EOF
   exit 0
 fi